package fiuba.algo3.vista;

import java.awt.Color;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

import org.jdom2.Document;
import org.jdom2.output.XMLOutputter;

import fiuba.algo3.controlador.Controlador;
import fiuba.algo3.controlador.ControladorFlechitas;
import fiuba.algo3.juego.JuegoGPS;
import fiuba.algo3.juego.Puntaje;
import fiuba.algo3.partida.Partida;

public class VistaJuego extends JFrame implements Observer, ActionListener {

	private JFrame miFrame;
	private JLabel movimientos;
	private JMenuBar menuBar1;
	private JMenu archivo, ayuda;
	private JMenuItem guardar, abandonar, salir, acerca, reglas;
	private JuegoGPS modelo; // referencia al modelo
	private Partida miPartida;

	private MyGamePanel panelDeJuego;
	private ReferencePanel panelReferencias;

	// Clase auxiliar para escuchar el evento de cerrado de la ventana
	public static class CloseListener extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			e.getWindow().setVisible(false);
			System.exit(0);
		}
	}

	// Constructor de la vista
	public VistaJuego(JuegoGPS modelo, Controlador control, JFrame frameTemp, ControladorFlechitas controlFlechas) {
		
		this.modelo = modelo;
		this.miPartida = modelo.getPartida();
		
		this.miFrame = frameTemp;
		JPanel contentPane = new JPanel();
		frameTemp.setContentPane(contentPane);
		contentPane.setLayout(null);

		Panel panelBotones = new Panel(); // creamos un panel para los botones

		JButton botonSubir = new JButton(); // boton para subir el auto
		ImageIcon FlechaArriba = new ImageIcon("imagenes/FlechaArriba2.png");
		botonSubir.setBackground(Color.LIGHT_GRAY);
		botonSubir.setIcon(FlechaArriba);
		
		JButton botonBajar = new JButton(); // boton para bajar el auto
		ImageIcon FlechaAbajo = new ImageIcon("imagenes/FlechaAbajo2.png");
		botonBajar.setBackground(Color.LIGHT_GRAY);
		botonBajar.setIcon(FlechaAbajo);
		
		JButton botonDerecha = new JButton(); // boton para bajar el
		ImageIcon FlechaDerecha = new ImageIcon("imagenes/FlechaDerecha2.png");		
		botonDerecha.setBackground(Color.LIGHT_GRAY);
		botonDerecha.setIcon(FlechaDerecha);
		
		JButton botonIzquierda = new JButton(); // boton para bajar el auto
		ImageIcon FlechaIzquierda = new ImageIcon("imagenes/FlechaIzquierda2.png");
		botonIzquierda.setBackground(Color.LIGHT_GRAY);
		botonIzquierda.setIcon(FlechaIzquierda);

		panelBotones.setBounds(775, 530, 330, 170);
		panelBotones.setLayout(null);

		JLabel etiqueta = new JLabel("Botones para controlar el vehiculo");
		etiqueta.setBounds(45, 0, 200, 13);
		panelBotones.add(etiqueta);
		botonSubir.setBounds(100, 15, 70, 69);
		botonBajar.setBounds(100, 85, 70, 69);
		botonDerecha.setBounds(175, 85, 70, 69);
		botonIzquierda.setBounds(25, 85, 70, 69);
		
		panelBotones.add(botonSubir); // agregamos el boton de "Subir" al panel
		panelBotones.add(botonBajar); // agregamos el boton de "Bajar" al panel
		panelBotones.add(botonDerecha); // agregamos el boton de "Bajar" al panel
		panelBotones.add(botonIzquierda); // agregamos el boton de "Bajar" al panel

		frameTemp.add(panelBotones); // agregamos el panel al marco
		frameTemp.setBounds(0, 0, 1125,750); // seteamos las dimensiones del marco
		frameTemp.setVisible(true); // mostramos el marco

		// agregamos el listener del evento de cerrado de la ventana
		frameTemp.addWindowListener(new CloseListener());

		// agregamos el listener de los botones "Subir" y "Bajar" "Derecha" e "Izquierda"
		// Notar que los listeners se los pedimos al controlador
		botonSubir.addKeyListener(controlFlechas);
		botonBajar.addKeyListener(controlFlechas);
		botonDerecha.addKeyListener(controlFlechas);
		botonIzquierda.addKeyListener(controlFlechas);
		
		botonSubir.addActionListener(control.getListenerBotonSubir());
		botonBajar.addActionListener(control.getListenerBotonBajar());
		botonDerecha.addActionListener(control.getListenerBotonDerecha());
		botonIzquierda.addActionListener(control.getListenerBotonIzquierda());

		// Conectamos esta vista con el modelo
		this.modelo = modelo;
		this.modelo.addObserver(this);

		panelDeJuego = new MyGamePanel(modelo.getPartida());
		panelDeJuego.setBounds(15, 0, 680, 680);
		frameTemp.add(panelDeJuego);

		// Barra
		menuBar1 = new JMenuBar();

		// Menu
		archivo = new JMenu("Archivo");
		ayuda = new JMenu("Ayuda");

		
	

		guardar = new JMenuItem("Guardar..");
		ActionListener listenerGuardar = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				
				System.out.println("Guardar..");
				
				new VentanaGuardarPartida(miPartida);
				
				
			
			}
		};
		guardar.addActionListener(listenerGuardar);

		salir = new JMenuItem("Cerrar juego");
		salir.addActionListener(this);
		
		acerca = new JMenuItem("Acerca de..");
		ActionListener listenerAcerca = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				System.out.println("Acerca");
				new VentanaAcerca();
			}
		};
		acerca.addActionListener(listenerAcerca);

		reglas = new JMenuItem("Regla de juego..");
		ActionListener listenerReglas = new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				new VentanaTutorialEmergente();

			}

		};
		reglas.addActionListener(listenerReglas);

		abandonar = new JMenuItem("Abandonar partida");
		abandonar.addActionListener(this);

		// agrego items a cada menu
		archivo.add(guardar);
		archivo.add(abandonar);
		archivo.addSeparator();
		archivo.add(salir);

		ayuda.add(acerca);
		ayuda.add(reglas);

		// agrego menues a la barra
		menuBar1.add(archivo);
		menuBar1.add(ayuda);

		frameTemp.setJMenuBar(menuBar1); // seteamos la barra a la ventana

		panelReferencias = new ReferencePanel();
		frameTemp.add(panelReferencias);
		panelReferencias.setBounds(775, 80, 300, 425);

		movimientos = new JLabel("Movimientos: "
				+ modelo.getCantidadDeMovimientos());
		movimientos.setBounds(775, 25, 100, 30);
		frameTemp.add(movimientos);

		JLabel maxMovimientos = new JLabel("Movimientos maximos permitidos: "
				+ modelo.getPartida().getCantidadDeMovimientosMaximos());
		maxMovimientos.setBounds(775, 50, 250, 30);
		frameTemp.add(maxMovimientos);

		frameTemp.paintComponents(frameTemp.getGraphics());
	}

	@Override
	public void update(Observable obs, Object obj) {
		movimientos.setText("Movimientos: " + modelo.getCantidadDeMovimientos());
		panelDeJuego.repaint();
		System.out.println("pintando");

		if (modelo.getPartida().superoCantidadDeMovimientosLimite()) {
			miFrame.setJMenuBar(null);
			modelo.deleteObservers();
			new VentanaPerdedor(modelo, miFrame);

		} 
		
		else if (modelo.getPartida().vehiculoEnLlegada()) {
			miFrame.setJMenuBar(null);
			modelo.deleteObservers();
			Puntaje unPuntaje = new Puntaje();
			unPuntaje.setNombre(modelo.getUsuarioActual());
			unPuntaje.setPuntaje(modelo.getPartida().calcularPuntaje());
			modelo.agregarNuevoPuntajeMaximo(unPuntaje);
			Document doc = new Document(modelo.serializar());
		try {
			XMLOutputter xmlOutput = new XMLOutputter();
			// display nice nice xmlOutput.setFormat(Format.getPrettyFormat());
			xmlOutput.output(doc, new FileWriter("juego.xml"));

			System.out.println("File Saved!");
			} catch (IOException io) {
			System.out.println(io.getMessage());
			}
			new VentanaResultado(modelo, miFrame);
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == abandonar) {
			miFrame.setJMenuBar(null);
			modelo.deleteObservers();
			new VentanaMenuDelJuego(modelo, miFrame);
		}
		
		if(e.getSource() == salir){
			System.exit(0);
		}
	}
	
	

}